# Copyright (c) 2019 Presto Labs Pte. Ltd.
# Author: yuxuan

import functools

from absl import flags

import coin.proto.archive_flag_pb2 as afpb
import coin.strategy.mm.tool.archive_base as abase

FLAGS = flags.FLAGS


def define_fastfeed_flags():
  flags.DEFINE_string('feed_cache_dir', '/remote/iosg/coin-2/feed_cache', '')
  flags.DEFINE_string('exchange', '', 'Do not use. For fastfeed only.')
  flags.DEFINE_string('market_type', '', 'Do not use. For fastfeed only.')
  flags.DEFINE_string('time_range', '0-24', 'Do not use. For fastfeed only.')
  flags.DEFINE_string('worker_ids', '1,2', 'Do not use. For fastfeed only.')
  flags.DEFINE_bool('use_feed_cache', True, '')
  flags.DEFINE_string('feed_root', '/remote/iosg/coin/data/flow', '')

  flags.DEFINE_string('okex_api_override', '', '')
  flags.DEFINE_string('binance_api_override', '', '')
  flags.DEFINE_string('quoinex_api_override', '', '')
  flags.DEFINE_string(
      'api_override',
      'Futures:Okex=v3.snapshot,Spot:Okex=v3.snapshot,Spot:Quoinex=single_channel,Spot:Binance=v1.snapshot,Spot:Huobi=v1.snapshot',
      'e.g. Futures:Okex=v3_realtime,Futures:Binance=l1_realtime')
  flags.DEFINE_string('feed_machine', '', '')


def get_base_flags(trading_date):
  if hasattr(trading_date, 'strftime'):
    trading_date = trading_date.strftime('%Y%m%d')
  assert flags.FLAGS.exchange is not None, flags.FLAGS.exchange
  assert flags.FLAGS.market_type is not None, flags.FLAGS.market_type
  return afpb.BaseFlagProto(trading_date=trading_date,
                            exchange=flags.FLAGS.exchange,
                            market_type=flags.FLAGS.market_type,
                            time_range=flags.FLAGS.time_range)


def get_api_override_dict():
  api_overrides = dict()
  for kv in FLAGS.api_override.split(','):
    k, v = kv.split('=')
    api_overrides[k] = v

  def _update_dict_func(exchange, api_override):
    if not api_override:
      return
    if '=' in api_override:
      for kv in api_override.split(','):
        k, v = kv.split('=')
        if k in api_overrides:
          api_overrides['%s:%s' % (k, exchange)] = v
    else:
      api_overrides['Futures:%s' % exchange] = api_override
      api_overrides['Spot:%s' % exchange] = api_override

  _update_dict_func('Okex', FLAGS.okex_api_override)
  _update_dict_func('Binance', FLAGS.binance_api_override)
  _update_dict_func('Quoinex', FLAGS.quoinex_api_override)
  return api_overrides


def _update_api_override_flag():
  api_overrides = get_api_override_dict()
  api_override_str = ','.join(['%s=%s' % (k, v) for k, v in api_overrides.items()])
  if api_override_str != FLAGS.api_override:
    flags.FLAGS.api_override = api_override_str


def run_from_archive_or_cache(trading_date, machine, products, strategy, fastfeed):
  _update_api_override_flag()
  flags.FLAGS.use_feed_cache = fastfeed
  baseflags = get_base_flags(trading_date)
  fsflags = abase.get_feed_subscription_flags()
  abase.run_from_archive_base(baseflags=baseflags,
                              feed_sub_flags_proto=fsflags,
                              products=products,
                              on_book_reset=functools.partial(strategy.on_book_reset, products))
